package com.rbac.api.service.impl;

import com.alibaba.fastjson.JSON;
import com.rbac.api.constant.AdminConstant;
import com.rbac.api.controller.enums.HintMessageEunm;
import com.rbac.api.controller.enums.SaveStatusTypeEnum;
import com.rbac.api.controller.request.*;
import com.rbac.api.controller.response.Response;
import com.rbac.api.mybatis.entity.AdminUsersEntity;
import com.rbac.api.mybatis.mapper.AdminUsersMapper;
import com.rbac.api.service.common.AdminCommonService;
import com.rbac.api.service.UsersCommonService;
import com.rbac.api.service.common.InsActionLogService;
import com.rbac.api.service.common.SaveStatusCommService;
import com.rbac.api.utils.ApiPublicUtil;
import com.rbac.utils.commUtils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class UsersCommonServiceImpl implements UsersCommonService {

    //操作 redis
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    //事务
    @Autowired
    private TransactionService transactionService;

    //管理员表
    @Autowired
    private AdminUsersMapper adminUsersMapper;

    ///操作管理员token公共service
    @Autowired
    private AdminCommonService adminCommonService;

   ///记录操作日志service
    @Autowired
    private InsActionLogService insActionLogService;

    //日志操作
    private static final LogUtil logger = LogUtil.getLogger(UsersCommonServiceImpl.class);

    ///修改状态公共service
    @Autowired
    private SaveStatusCommService saveStatusCommService;






    ///登录
    @Override
    public Object commonUsersLoginService(PostUserLoginRequest userLoginRequest,HttpServletRequest request) throws Exception {
        //根据账号获取用户数据
        AdminUsersEntity adminUsersOne =  adminUsersMapper.selectLoginByUserAccount(userLoginRequest.getAccount());
        //如果不存在数据
        if(adminUsersOne == null){
            //由于账号不存在，提示账号或密码错误
            return new Response(HintMessageEunm.EXCEPTION_ACCOUNT_NOT_EXISTS_ERROR);
        }
        //客户端输入的密码进行加密
        String clientPwd = userLoginRequest.getPassword();
        clientPwd = ToolUtil.getEncryptAfterPwd(clientPwd,adminUsersOne.getUserSalt());


        //判断密码
        if(!(clientPwd.equals(adminUsersOne.getUserPwd()))){
            //提示密码错误
            return new Response(HintMessageEunm.EXCEPTION_ACCOUNT_OR_PASSWORD_ERROR);
        }
        //判断管理员的状态
        Integer userStatus = adminUsersOne.getUserStatus();
        if(org.springframework.util.StringUtils.isEmpty(userStatus) || !(userStatus.equals(AdminConstant.ADMIN_USERS_EFFECTIVE_STATUS))){
            return new Response(HintMessageEunm.EXCEPTION_ACCOUNT_ALREADY_FROZEN_ERROR);
        }

        //token
        String token = RandomStringUtil.getUUID();

        ///记录操作
        insActionLogService.InsOneActionLogService("登录",adminUsersOne.getUserNo(), ToolUtil.getClientIp(request),"管理员 {0} 在 {1} 登录了系统", adminUsersOne.getUserAccount(), ToolUtil.getStringTodayTime());

        //将当前管理员信息存储到 redis 内
        Map<String,Object> rm = new HashMap<>();
        rm.put("account",adminUsersOne.getUserAccount());//账号
        rm.put("name",adminUsersOne.getUserName());//昵称
        rm.put("userno",adminUsersOne.getUserNo());//编号
        rm.put("token",token);
        String userInfoStr = JSON.toJSONString(rm);
        stringRedisTemplate.opsForValue().set(token,userInfoStr,AdminConstant.ADMIN_SUPER_USERS_LIFE_CYCLE,TimeUnit.HOURS);

        return new Response(HintMessageEunm.EXCEPTION_SUCCESS_DEFAULT,rm);
    }

    ///退出
    @Override
    public Object commonUsersOutService(HttpServletRequest request) throws Exception {
        //获取 token
        String token = adminCommonService.getTokenByRequestHeader(request);
        //提示 token 不存在
        if(!(stringRedisTemplate.hasKey(token))){
            return new Response(HintMessageEunm.EXCEPTION_OUT_ACTION_ERROR);
        }

        ///获取管理员编号和账号
        String userNo = adminCommonService.getUserInfoFieldByRequestHeader(request,"userno");
        String userAccount = adminCommonService.getUserInfoFieldByRequestHeader(request,"account");
        ///记录操作
        insActionLogService.InsOneActionLogService("退出",userNo, ToolUtil.getClientIp(request),"管理员 {0} 在 {1} 退出了系统",userAccount, ToolUtil.getStringTodayTime());

        //删除 token
        stringRedisTemplate.delete(token);
        //
        return new Response(HintMessageEunm.EXCEPTION_SUCCESS_DEFAULT);
    }


    ////管理员修改密码
    @Override
    public Object userSavePassword(PostUserSavePwdRequest userSavePwdRequest, HttpServletRequest request) throws Exception {
        String token = adminCommonService.getTokenByRequestHeader(request);///token
        String account = adminCommonService.getUserInfoFieldByRequestHeader(request,"account");
        String actionUserNo = adminCommonService.getUserInfoFieldByRequestHeader(request,"userno");
        String salt = RandomStringUtil.getRandomStringByLength(6);//随机生成的加密盐
        String madAfterPwd = ToolUtil.getEncryptAfterPwd(userSavePwdRequest.getUserPwd(),salt);//客户端解密后的密码

        try{
            ///管理员信息实体
            AdminUsersEntity userOne = new AdminUsersEntity();
            userOne.setUserAccount(account);///登录账号
            userOne.setUserPwd(madAfterPwd);///登录密码
            userOne.setUserSalt(salt);///加密盐
            userOne.setLastUpdateUid(actionUserNo);///操作人编号
            userOne.setLastUpdateTime(ToolUtil.getTodayTime());///最后一次更新时间
            Integer  res = adminUsersMapper.savePasswordByUserAccountMapper(userOne);
            if(res.equals(1)){
                stringRedisTemplate.delete(token);//删除 token
            }
        }catch (Exception e){
            //LOG
            logger.error("管理员修改密码出现异常："+e);
            //提示出现异常
            return new Response(HintMessageEunm.EXCEPTION_SAVE_MY_PASSWORD_ERROR);
        }

        //操作成功
        return new Response(HintMessageEunm.EXCEPTION_SUCCESS_DEFAULT);
    }




    ///获取管理员列表
    @Override
    public Object getUsersListService(PostUsersListRequest usersListRequest) throws Exception {
        //数据总条数
        Integer countDataNum = adminUsersMapper.getUsersListCountSelective(usersListRequest);
        //没有数据则返回空数据
        if(countDataNum.equals(AdminConstant.DEFAULT_NO_DATA_VALUE_NUMBER)){
            return new Response(HintMessageEunm.EXCEPTION_SUCCESS_DEFAULT,new String[]{});
        }

        //当前页
        Integer pageIndex = usersListRequest.getPageIndex();
        //页面显示条数
        Integer pageSize = usersListRequest.getPageSize();

        PagenationUtil pageClass = new PagenationUtil(pageSize,pageIndex,countDataNum);

        //获取页面数据
        List<AdminUsersEntity> nowPageBasicsData = adminUsersMapper.getUsersListDataSelective(usersListRequest,pageClass.getStartRow(),pageSize);

        ///
        return new Response(HintMessageEunm.EXCEPTION_SUCCESS_DEFAULT, ApiPublicUtil.AssemblyReturnItem(countDataNum,pageIndex,pageSize,nowPageBasicsData));
    }


    ///新增管理员
    @Override
    public Object usersAddService(PostUserAddRequest userAddRequest,HttpServletRequest request) throws Exception {

        String actionUid = adminCommonService.getUserNoByRequestHeader(request);
        String actionAccount = adminCommonService.getUserInfoFieldByRequestHeader(request,"account");
        String salt = RandomStringUtil.getRandomStringByLength(6);//随机生成的加密盐
        String userNo = RandomStringUtil.getUUID();///管理员编号
        String madAfterPwd = ToolUtil.getEncryptAfterPwd(userAddRequest.getUserPwd(),salt);//客户端解密后的密码
        String clientAccount = userAddRequest.getUserAccount();///登录账号
        Integer countAccountNumber = adminUsersMapper.checkAccountByUserAccountMapper(clientAccount);
        if(countAccountNumber > 0){
            return new Response(HintMessageEunm.EXCEPTION_ACCOUNT_ALREADY_EXISTENCE_ERROR,userAddRequest);
        }

        ///管理员信息实体
        AdminUsersEntity userOne = new AdminUsersEntity();
        userOne.setUserNo(userNo);//管理员编号
        userOne.setUserAccount(clientAccount);///登录账号
        userOne.setUserName(userAddRequest.getUserName());///管理员昵称
        userOne.setUserPwd(madAfterPwd);///登录密码
        userOne.setUserSalt(salt);///加密盐
        userOne.setCreateUid(actionUid);///创建人编号
        userOne.setCreateTime(ToolUtil.getTodayTime());///创建时间


        //开启事务
        TransactionStatus transactionStatus = transactionService.begin();

        try{
            adminUsersMapper.usersAddMapper(userOne);
            insActionLogService.InsOneActionLogService("新增管理员",actionUid, ToolUtil.getClientIp(request),"管理员 {0} 在 {1} 进行了新增管理员操作，产生的数据id为{2}",actionAccount, ToolUtil.getStringTodayTime(),userOne.getId());
        }catch (Exception e){
            //LOG
            logger.error("新增管理员出现异常："+e);
            //回滚事务
            transactionService.rollback(transactionStatus);
            //提示出现异常
            return new Response(HintMessageEunm.EXCEPTION_ADD_NEW_ADMIN_ERROR);
        }

        //提交事务
        transactionService.commit(transactionStatus);
        //操作成功
        return new Response(HintMessageEunm.EXCEPTION_SUCCESS_DEFAULT);
    }


    ///修改管理员状态
    @Override
    public Object usersSaveStatusService(PostUserSaveStatusRequest userSaveStatusRequest, HttpServletRequest request) throws Exception {
        String actionNameStr = "修改管理员状态";
        String nowUserNo = adminCommonService.getUserInfoFieldByRequestHeader(request,"userno");
        String actionAccount = adminCommonService.getUserInfoFieldByRequestHeader(request,"account");
        Integer id = userSaveStatusRequest.getId();
        Integer userStatus = userSaveStatusRequest.getUserStatus();
        Integer nowStatus = userSaveStatusRequest.getNowStatus();
        Date t = ToolUtil.getTodayTime();


        return this.saveStatusCommService.common(SaveStatusTypeEnum.USER_TABLE_SAVE_STATUS.getValue(),actionNameStr,actionAccount,userStatus,nowUserNo,t,id,nowStatus,request);
    }
}
